//
// Created by liuhuan on 2022/4/29.
//

#ifndef RUIYAN_PTZ_DATADEFINE_H
#define RUIYAN_PTZ_DATADEFINE_H
#include <android/log.h>
#define  GND_LOGE(...)   __android_log_print(ANDROID_LOG_ERROR,"GndControl",__VA_ARGS__);
#define  GND_LOGD(...)   __android_log_print(ANDROID_LOG_DEBUG,"GndControl",__VA_ARGS__);

/**
 * PTZ方向宏定义
 */
#define PROTOCOL_VER "20220402_1"

#define PACKHEADER_0 0xEB
#define PACKHEADER_1 0x90

#define PACKHEADERIMAGE_0 0xEE
#define PACKHEADERIMAGE_1 0x90

#define PTZ_UP 0x00
#define PTZ_DOWN 0x01
#define PTZ_LEFT 0x00
#define PTZ_RIGHT 0x01

#define PTZ_JUST  0x01
#define PTZ_NEGATIVE  0xFF
#define PTZ_ZERO  0x00

#define ZOOM_ENLARGE 0x00
#define ZOOM_NARROW 0x01

#define STATUSNONE 0

#define ON 1
#define OFF 0

#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

/**
 *  摄像头镜头类型枚举
 */
enum CamLensTypeEnum {
    zoomLens = 0x00,       //变焦镜头
    fixedFocusLens = 0x01, //定焦镜头
    irLens = 0x02,         //红外镜头
};

//地面端到天空端命令类型
enum GndToSkyCmdEnum {
    querySetDev = 0xA0, //查询设置设备信息,如查询当前的镜头类型、是否有激光测距信息、镜头框信息是否发送、设备状态 等等
    ptzMove = 0xA1,     //云台
    camZoom = 0xA2,     //镜头变焦、部分镜头可能无法变焦
    setDetectMode = 0xA3,//设置检测模式,以及设置是否返回检测框信息
    setTrackMode = 0xA4,//设置跟踪模式
    ptzMove_SpecifyAngle = 0xA5,    //云台转动到指定角度
    setOneShotMode = 0xA6, //设置单模板匹配模式

    updatePtzPid = 0xE1,  //修改云台追踪时,云台追踪PID算法参数
    queryPtzPid = 0xE2,   //查询云台追踪时,云台追踪PID算法参数
    queryAlgParams = 0xE3,//查询云台算法参数，多板需要多次查询
    updateAlgParams = 0xE4,//修改云台算法参数，多板需要多次设置
};

//天空端到地面端命令类型
enum SkyToGndCmdEnum {
    returnDevInfo = 0xB4,//返回设备信息
    returnBaseInfo = 0xB5,
    returnDetectInfo = 0xB6,
    returnTrackInfo = 0xB7,

    returnPtzPidInfo = 0xD1,
    returnAlgParamsInfo = 0xD2,
};

enum GndToSkyPtzTypeEnum {
    ptzType_Zero = 0xC1, //云台回归初始位
    ptzType_Yaw = 0xC2,  //方位角移动
    ptzType_Pitch = 0xC3,//俯仰角移动
    ptzType_Roll = 0xC4, //横滚角移动 ，两轴没有横滚角
};

enum DevModeEnum {
    SNone = 0xD1,
    DetectMode = 0xD2,
    TrackMode = 0xD3,
    OneShotMode = 0xD4 //单模板匹配模式
};

//云台状态
enum PtzStatusEnum {
    PtzNull,        //无云台
    PtzOk,          //云台正常
    PtzSelfCheck,   //云台自检
    PtzError,       //云台错误
};

enum DevStausEnum {
    DevNorMal,      //设备正常
    DevInit,        //设备
    DevOffline,     //设备离线
    CamOffline,      //镜头掉线
    DevError,       //设备错误
};

enum TrackStatusEnum {
    Tracking = 0,//跟踪中
    Lost = 1,    //完全丢失
    Losing = 2,  //暂时丢失，可能会找回
};

#pragma pack(1)

/**
 * 包头信息
 */
typedef struct common_header_stru {
    unsigned char header[2];                         //固定包头 固定值{0xeb,0x90}
    unsigned short len;                              //数据长度
    unsigned char identificationCode[2];             //设备识别码,目前是固定值{0x13,0x13}
    unsigned char cmd;                               //命令码

    common_header_stru() {
        header[0] = PACKHEADER_0;
        header[1] = PACKHEADER_1;
    }
} COMMON_HEADER_S;

/**
 *  地面到吊舱 查询设备信息指令
 */
typedef struct gnd_skynode_queryDev_stru {
    common_header_stru header;     //包头
    unsigned short infoReturnFreq; //0 ~ 100hz 基础信息返回频率， 如 云台角度、测距等。该返回频率并不代表每次都会去硬件读取，每个硬件都有独立的读取频率
    unsigned short crc;            //CRC校验
} GND_SKYNODE_QUERYDEV_S;

/**
 *  地面到吊舱 单指令云台控制命令
 */
typedef struct gnd_skynode_ptz_stru {
    common_header_stru header; //包头
    unsigned char ptzType;     //移动类型 ：0xC1; 云台回归初始位  0xC2;  方位角移动 0xC3; 俯仰角移动 ptzType_Roll = 0xC4; 横滚角移动 ，两轴没有横滚角
    unsigned char direction;   //转动方向 0x00 表示左或者上 , 0x01 表示右或者下,根据任务类型区分,归零置零
    unsigned short angle;      //转动角度 ，100~500 如果为0 或者超出范围默认为 5
    unsigned char speed;       //转动速度 ，100~255 如果为0 或者超出范围默认为 10
    unsigned short crc;        //CRC校验
} GND_SKYNODE_PTZ_S;

/**
 *  地面到吊舱 移动云台到指定角度
 */
typedef struct gnd_skynode_ptz_more_axis_stru {
    common_header_stru header; //包头
    char isYaw;    //是否移动方位角
    unsigned short yawAngle;         //方位角指定角度
    char isPitch;  //是否移动俯仰角
    unsigned short pitchAngle;       //俯仰角指定角度
    char isRoll;  //是否移动横滚角
    unsigned short rollAngle;       //横滚角角指定角度
    unsigned short crc;        //CRC校验
} GND_SKYNODE_PTZ_MORE_AXIS_S;

/**
 *  地面到吊舱 变焦控制指令
 */
typedef struct gnd_skynode_zoom_stru {
    common_header_stru header; //包头
    unsigned char devNo;        //要控制的设备编号
    unsigned char direction;   //变焦方向
    unsigned char speed;       //预留变焦速度值，目前大部分镜头是没有速度的概念的
    unsigned char destZoom;    //预留变倍到指定倍数，目前不支持
    unsigned short crc;        //CRC校验
} GND_SKYNODE_ZOOM_S;

/**
 *  地面到吊舱 设置检测模式,以及设置是否返回信息检测框，多光的情况下默认返回所有的框信息,改指令可以单独设置某个镜头设备可以开关返回框信息
 */
typedef struct gnd_skynode_setDetectMode_stru {
    common_header_stru header;    //包头
    unsigned char devNo;    //要设置返回的镜头类型  为0时 不设置
    unsigned char returnBoxOnOff; //返回框信息开关
    unsigned short crc;           //CRC校验
} GND_SKYNODE_SETDETECTMODE_S;

/**
*  地面到吊舱 设置检测模式以及设置检测框
*/
typedef struct gnd_skynode_setTrackMode_stru {
    common_header_stru header;    //包头
    unsigned char devNo;          //设备编号
    unsigned char isMovePtz;      //云台是否跟进跟踪，默认跟进 ON OFF ，暂未生效
    unsigned char classId;        //目标分类
    unsigned short xMin;          //按画面比例 xMin
    unsigned short yMin;          //按画面比例 xMin
    unsigned short xMax;          //按画面比例 xMax
    unsigned short yMax;          //按画面比例 yMax
    unsigned short crc;           //CRC校验
} GND_SKYNODE_SETTRACKMODE_S;

/**
 * 设备ip信息
 */
struct DeviceInfo {
    unsigned char no;                      //设备编号
    unsigned char camType;                 //设备类型
    unsigned short port = 0;               //rtsp端口
    unsigned char devStatus;               //设备状态
};

typedef struct skynode_gnd_devInfo_stru {
    common_header_stru headerS;      //包头
    unsigned char isRanging;        //是否有测距
    unsigned char devNums;          //设备数量
//    std::vector<DeviceInfo> devices;              //设备信息
//    unsigned short crc;             //CRC校验
} SKYNODE_GND_DEVINFO_S;

typedef struct skynode_gnd_baseInfo_stru {
    common_header_stru header;      //包头
    unsigned char currentMode;      //当前模式
    unsigned char ptzStatus;        //云台是否可控
    short yaw;                      //方位角 正负
    short pitch;                    //俯仰角 正负
    short roll;                     //横滚值 正负
    unsigned char rangeValid;       //测距是否有效
    unsigned short rangVal;        //测距值 精度0.1
    unsigned char mainZoom;         //主zoom
    unsigned short crc;             //CRC校验
} SKYNODE_GND_BASEINFO_S;

typedef struct boundingBox_stru {
    char classId;
    unsigned short xmin; //比例值
    unsigned short ymin;
    unsigned short xmax;
    unsigned short ymax;
    unsigned char score;
} BoundingBox;

typedef struct skynode_gnd_detectInfos_stru {
    common_header_stru header;      //包头
    unsigned char devNo;            //内部的设备编号
    unsigned char camLensType;      //返回的镜头类型
    unsigned short zoom;             //当前zoom的倍率
    unsigned char boxLen;           //框数量 如果框为0
//    std::vector<BoundingBox> boxs;  //框
//    unsigned short crc;             //CRC校验
} SKYNODE_GND_DETECTINFOS_S;

typedef struct skynode_gnd_trackInfo_stru {
    common_header_stru header;      //包头
    unsigned char devNo;            //内部设备编号
    unsigned char camLensType;      //在跟踪的镜头类型
    unsigned short zoom;             //当前zoom的倍率
    unsigned char destIsLost;       //目标是否丢失 如果丢失了 以下信息就无效
    BoundingBox trackBox;           //跟踪框
    short dstAndCenterAngleX;       //目标距离视场中心的角度X
    short dstAndCenterAngleY;       //目标距离视场中心的角度Y

    short yaw;                      //方位角 正负
    short pitch;                    //俯仰角 正负
    short roll;                     //横滚值 正负

    unsigned short crc;             //CRC校验
} SKYNODE_GND_TRACKINFO_S;

#pragma pack()

inline unsigned short crcCount(char *buff, int len) {
    unsigned short crc = 0x0;
    unsigned short checksum = 0;

    for (int i = 0; i < len; i++) {
        crc += *buff++;
    }
    checksum = crc & 0xff;
    return checksum;
}
#endif //RUIYAN_PTZ_DATADEFINE_H
